<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <title>Cesium 高质量模型展示</title>
    <link href="https://cesium.com/downloads/cesiumjs/releases/1.95/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
    <style>
        html,
        body,
        #cesiumContainer {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
            overflow: hidden;
            background: linear-gradient(135deg, #1a1a1a 0%, #2d2d2d 50%, #1a1a1a 100%);
        }

        .toolbar {
            position: absolute;
            top: 10px;
            left: 10px;
            padding: 10px;
            background: rgba(42, 42, 42, 0.8);
            border-radius: 4px;
            z-index: 999;
        }

        .toolbar button {
            margin: 5px;
            padding: 8px 15px;
            background: #4CAF50;
            border: none;
            color: white;
            border-radius: 3px;
            cursor: pointer;
            transition: background-color 0.3s;
        }

        .toolbar button:hover {
            background: #45a049;
        }

        /* 性能监控面板 */
        .performance-panel {
            position: absolute;
            top: 10px;
            right: 10px;
            z-index: 999;
            background: rgba(0, 0, 0, 0.8);
            color: white;
            padding: 10px;
            border-radius: 4px;
            font-family: monospace;
            font-size: 12px;
            min-width: 200px;
        }

        /* 模型管理面板 */
        .model-manager-panel {
            position: absolute;
            top: 70px;
            right: 10px;
            width: 320px;
            max-height: 600px;
            overflow-y: auto;
            background: rgba(42, 42, 42, 0.95);
            border: 1px solid #555;
            border-radius: 8px;
            padding: 15px;
            color: white;
            font-family: Arial, sans-serif;
            font-size: 12px;
            z-index: 999;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
        }

        .model-item {
            background: rgba(0, 0, 0, 0.3);
            border: 1px solid #666;
            border-radius: 6px;
            padding: 12px;
            margin-bottom: 12px;
            transition: background-color 0.3s;
        }

        .model-item:hover {
            background: rgba(0, 0, 0, 0.5);
        }

        .model-item h4 {
            margin: 0 0 10px 0;
            color: #4CAF50;
            font-size: 14px;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .model-controls {
            display: flex;
            align-items: center;
            margin: 8px 0;
            gap: 8px;
        }

        .model-controls label {
            min-width: 60px;
            font-size: 11px;
        }

        .model-controls input[type="checkbox"] {
            margin-right: 5px;
        }

        .model-controls input[type="range"] {
            flex: 1;
            margin: 0 8px;
        }

        .model-controls .range-value {
            min-width: 35px;
            text-align: right;
            font-size: 10px;
            color: #ccc;
        }

        .color-picker {
            width: 30px;
            height: 22px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }

        .model-button {
            padding: 4px 8px;
            margin: 0 2px;
            border: none;
            border-radius: 3px;
            cursor: pointer;
            font-size: 10px;
            transition: background-color 0.3s;
        }

        .locate-btn {
            background: #2196F3;
            color: white;
        }

        .locate-btn:hover {
            background: #1976D2;
        }

        .delete-btn {
            background: #f44336;
            color: white;
        }

        .delete-btn:hover {
            background: #d32f2f;
        }

        .load-status {
            font-size: 12px;
            padding: 2px 6px;
            border-radius: 3px;
            margin-left: 5px;
        }

        .status-loaded {
            background: #4CAF50;
            color: white;
        }

        .status-loading {
            background: #FF9800;
            color: white;
        }

        .status-error {
            background: #f44336;
            color: white;
        }

        .status-pending {
            background: #607D8B;
            color: white;
        }

        #cesiumContainer canvas {
            background-color: transparent !important;
        }

        /* 建筑信息面板样式 */
        .building-info-panel {
            position: absolute;
            background: linear-gradient(135deg, rgba(0, 0, 0, 0.95), rgba(30, 30, 30, 0.95));
            color: white;
            padding: 0;
            border-radius: 15px;
            font-family: 'Microsoft YaHei', Arial, sans-serif;
            font-size: 14px;
            max-width: 450px;
            max-height: 500px;
            overflow-y: auto;
            box-shadow: 0 15px 35px rgba(0, 0, 0, 0.7);
            z-index: 10000;
            border: 3px solid #ffff00;
            backdrop-filter: blur(15px);
            user-select: none;
            display: none;
        }

        .panel-header {
            background: rgba(255, 255, 0, 0.2);
            padding: 15px 20px;
            border-radius: 12px 12px 0 0;
            border-bottom: 2px solid #ffff00;
            cursor: move;
            text-align: center;
        }

        .panel-header:hover {
            background: rgba(255, 255, 0, 0.3);
        }

        .panel-header h3 {
            margin: 0;
            color: #ffff00;
            font-size: 18px;
        }

        .drag-hint {
            color: #87ceeb;
            font-size: 11px;
            margin-top: 5px;
        }

        .panel-content {
            padding: 20px;
        }

        .info-grid {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 15px;
            margin-bottom: 15px;
        }

        .info-box {
            background: rgba(0, 0, 0, 0.3);
            padding: 10px;
            border-radius: 8px;
            border: 1px solid #333;
        }

        .info-section {
            margin: 15px 0;
            padding: 12px;
            border-radius: 8px;
        }

        .location-section {
            background: rgba(0, 191, 255, 0.1);
            border-left: 3px solid #00bfff;
        }

        .status-section {
            background: rgba(0, 255, 0, 0.1);
            border-left: 3px solid #00ff00;
        }

        .button-group {
            display: flex;
            gap: 10px;
            margin-top: 20px;
        }

        .panel-button {
            flex: 1;
            padding: 8px 15px;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            font-size: 12px;
            transition: all 0.3s;
        }

        .focus-button {
            background: #2196F3;
            color: white;
        }

        .focus-button:hover {
            background: #1976D2;
            transform: translateY(-1px);
        }

        .close-button {
            background: #f44336;
            color: white;
        }

        .close-button:hover {
            background: #d32f2f;
            transform: translateY(-1px);
        }

        /* 左下角建筑控制面板 */
        .building-control-panel {
            position: absolute;
            bottom: 10px;
            left: 10px;
            background: rgba(42, 42, 42, 0.9);
            border: 1px solid #555;
            border-radius: 8px;
            padding: 15px;
            color: white;
            font-family: Arial, sans-serif;
            font-size: 13px;
            z-index: 999;
            min-width: 200px;
        }

        .checkbox-group {
            margin-top: 10px;
        }

        .checkbox-item {
            margin: 8px 0;
            display: flex;
            align-items: center;
            cursor: pointer;
        }

        .checkbox-item input[type="checkbox"] {
            margin-right: 8px;
        }

        /* 高亮样式 */
        .highlight-selected {
            border: 3px solid #ff0000 !important;
            background-color: rgba(255, 0, 0, 0.3) !important;
        }

        /* 搜索框样式 */
        .search-panel {
            position: absolute;
            top: 10px;
            right: 350px;
            z-index: 999;
            width: 300px;
        }

        .search-container {
            display: flex;
            background: rgba(42, 42, 42, 0.9);
            border: 1px solid #555;
            border-radius: 8px;
            padding: 8px;
            align-items: center;
            gap: 5px;
        }

        #buildingSearchInput {
            flex: 1;
            padding: 8px 12px;
            border: none;
            border-radius: 5px;
            background: rgba(255, 255, 255, 0.1);
            color: white;
            font-size: 14px;
            outline: none;
        }

        #buildingSearchInput::placeholder {
            color: #ccc;
        }

        #buildingSearchInput:focus {
            background: rgba(255, 255, 255, 0.2);
            box-shadow: 0 0 5px rgba(76, 175, 80, 0.5);
        }

        #searchButton,
        #clearSearchButton {
            padding: 8px 12px;
            border: none;
            border-radius: 5px;
            background: #4CAF50;
            color: white;
            cursor: pointer;
            font-size: 14px;
            transition: background-color 0.3s;
        }

        #searchButton:hover {
            background: #45a049;
        }

        #clearSearchButton {
            background: #f44336;
        }

        #clearSearchButton:hover {
            background: #d32f2f;
        }

        .search-results {
            margin-top: 5px;
            background: rgba(42, 42, 42, 0.95);
            border: 1px solid #555;
            border-radius: 8px;
            max-height: 300px;
            overflow-y: auto;
            display: none;
        }

        .search-result-item {
            padding: 10px 12px;
            color: white;
            cursor: pointer;
            border-bottom: 1px solid #555;
            transition: background-color 0.3s;
        }

        .search-result-item:hover {
            background: rgba(76, 175, 80, 0.3);
        }

        .search-result-item:last-child {
            border-bottom: none;
        }

        .search-result-name {
            font-weight: bold;
            color: #4CAF50;
        }

        .search-result-info {
            font-size: 12px;
            color: #ccc;
            margin-top: 3px;
        }

        .no-results {
            padding: 15px;
            text-align: center;
            color: #999;
            font-style: italic;
        }
    </style>
</head>

<body>
    <div id="cesiumContainer"></div>

    <!-- <div class="toolbar">
        <button id="topView">俯视图</button>
        <button id="frontView">正视图</button>
        <button id="leftView">左视图</button>
        <button id="rightView">右视图</button>
        <button id="resetView">重置视图</button>
        <button onclick="togglePerformance()">性能监控</button>
        <button onclick="toggleModelManager()">模型管理</button>
    </div> -->

    <!-- 搜索框 -->
    <div class="search-panel">
        <div class="search-container">
            <input type="text" id="buildingSearchInput" placeholder="搜索建筑名称..." autocomplete="off">
            <button id="searchButton">🔍</button>
            <button id="clearSearchButton" style="display: none;">✕</button>
        </div>
        <div id="searchResults" class="search-results"></div>
    </div>

    <!-- 性能监控面板 -->
    <div class="performance-panel" id="performancePanel" style="display: none;">
        <div style="color: #00ff00; font-weight: bold; margin-bottom: 10px;"> 性能监控</div>
        <div id="performanceContent">
            <!-- 性能数据-->
        </div>
    </div>

    <!-- 模型管理面板 -->
    <div class="model-manager-panel" id="modelManagerPanel" style="display: none;">
        <div style="color: #4CAF50; font-weight: bold; margin-bottom: 15px; cursor: move; display: flex; justify-content: space-between; align-items: center;"
            class="panel-header">
            模型管理器
            <span style="cursor: pointer; color: #ff6b6b; font-size: 16px;" onclick="toggleModelManager()">✕</span>
        </div>
        <div id="modelList">
            <!-- 模型列表动态生成 -->
        </div>
        <div style="margin-top: 15px; padding-top: 15px; border-top: 1px solid #555;">
            <button onclick="loadAllModels()"
                style="width: 100%; padding: 10px; background: #4CAF50; border: none; color: white; border-radius: 5px; cursor: pointer; margin-bottom: 5px;">
                重新加载所有模型
            </button>
            <button onclick="resetAllModelsView()"
                style="width: 100%; padding: 10px; background: #2196F3; border: none; color: white; border-radius: 5px; cursor: pointer;">
                查看所有模型
            </button>
        </div>
    </div>

    <!-- 左下角建筑底面控制面板 -->
    <div class="building-control-panel">
        <h3>建筑底面控制</h3>
        <div class="checkbox-group">
            <label class="checkbox-item">
                <input type="checkbox" id="showFootprints" checked onchange="toggleBuildingFootprints()">
                显示建筑底面
            </label>
            <label class="checkbox-item">
                <input type="checkbox" id="enableSelection" checked onchange="toggleBuildingSelection()">
                启用建筑选择
            </label>
            <label class="checkbox-item">
                <input type="checkbox" id="showSchools" checked onchange="toggleSchoolsVisibility()">
                显示学校信息
            </label>
        </div>
    </div>

    <!-- 建筑信息面板 -->
    <div class="building-info-panel" id="buildingInfoPanel">
        <div class="panel-header" id="panelHeader">
            <h3>建筑信息</h3>
            <div class="drag-hint">拖动此区域移动面板</div>
        </div>
        <div class="panel-content" id="panelContent">
            <!-- 内容通过JavaScript动态填充 -->
        </div>
    </div>

    <script src="https://cesium.com/downloads/cesiumjs/releases/1.95/Build/Cesium/Cesium.js"></script>
    <script>
        // 天地图密钥
        const TIANDITU_KEY = '7b1be718ffdff9267b28ec5fa2b72f20';

        // 瓦片缓存配置
        const TILE_CACHE_CONFIG = {
            maxCacheSize: 500, // 最大缓存瓦片数量
            maxAge: 24 * 60 * 60 * 1000, // 缓存24小时（毫秒）
            requestThrottle: 100, // 请求节流间隔（毫秒）
            maxConcurrentRequests: 6 // 最大并发请求数
        };

        // 创建带缓存的天地图影像提供者
        function createCachedTiandituProvider(layerType = 'img', layerName = 'img') {
            const provider = new Cesium.UrlTemplateImageryProvider({
                url: `https://t{s}.tianditu.gov.cn/${layerType}_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=${layerName}&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=` + TIANDITU_KEY,
                subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
                tilingScheme: new Cesium.WebMercatorTilingScheme(),
                maximumLevel: 16, // 降低最大级别以减少请求
                minimumLevel: 0,
                // 添加缓存配置
                tileWidth: 256,
                tileHeight: 256,
                // 启用瓦片缓存
                enablePickFeatures: false,
                // 请求节流
                throttleRequests: true,
                throttleRequestsDelay: TILE_CACHE_CONFIG.requestThrottle
            });

            // 重写requestImage方法添加缓存逻辑
            const originalRequestImage = provider.requestImage;
            const tileCache = new Map();
            let activeRequests = 0;

            provider.requestImage = function (x, y, level, request) {
                // 生成缓存键
                const cacheKey = `${layerType}_${x}_${y}_${level}`;

                // 检查缓存
                const cached = tileCache.get(cacheKey);
                if (cached && (Date.now() - cached.timestamp < TILE_CACHE_CONFIG.maxAge)) {
                    console.log(`缓存命中: ${cacheKey}`);
                    return Promise.resolve(cached.image);
                }

                // 限制并发请求数
                if (activeRequests >= TILE_CACHE_CONFIG.maxConcurrentRequests) {
                    return new Promise((resolve, reject) => {
                        setTimeout(() => {
                            provider.requestImage(x, y, level, request).then(resolve).catch(reject);
                        }, TILE_CACHE_CONFIG.requestThrottle);
                    });
                }

                activeRequests++;
                console.log(`请求瓦片: ${cacheKey} (活跃请求: ${activeRequests})`);

                // 修复：确保返回Promise
                const requestPromise = originalRequestImage.call(this, x, y, level, request);

                // 检查返回值是否为Promise
                if (!requestPromise || typeof requestPromise.then !== 'function') {
                    activeRequests--;
                    console.warn(`瓦片请求返回非Promise: ${cacheKey}`);
                    return Promise.reject(new Error('Invalid request response'));
                }

                return requestPromise
                    .then(image => {
                        activeRequests--;

                        // 缓存成功获取的瓦片
                        tileCache.set(cacheKey, {
                            image: image,
                            timestamp: Date.now()
                        });

                        // 清理过期缓存
                        if (tileCache.size > TILE_CACHE_CONFIG.maxCacheSize) {
                            cleanOldCache();
                        }

                        console.log(`瓦片获取成功: ${cacheKey} (缓存大小: ${tileCache.size})`);
                        return image;
                    })
                    .catch(error => {
                        activeRequests--;
                        console.warn(`瓦片获取失败: ${cacheKey}`, error);

                        // 返回空白瓦片避免无限重试
                        const blankImage = new Image();
                        blankImage.src = '';
                        return Promise.resolve(blankImage);
                    });
            };

            // 清理过期缓存
            function cleanOldCache() {
                const now = Date.now();
                const toDelete = [];

                for (const [key, value] of tileCache.entries()) {
                    if (now - value.timestamp > TILE_CACHE_CONFIG.maxAge) {
                        toDelete.push(key);
                    }
                }

                toDelete.forEach(key => tileCache.delete(key));
                console.log(`清理了 ${toDelete.length} 个过期缓存`);
            }

            return provider;
        }

        // 全局变量
        let selectedBuilding = null;
        let viewer = null;
        let modelCenter = null;
        let modelRadius = null;
        let buildingFootprintDataSource = null;
        let buildingFootprints = [];

        // 多模型管理变量
        let tilesets = [];  // 存储所有加载的模型
        let modelConfigs = [
            {
                id: 'model_main',
                name: '珠港新城',
                url: './models/tileset.json',
                visible: true,
                color: Cesium.Color.WHITE,
                alpha: 1.0,
                status: 'pending'  // pending, loading, loaded, error
            },
            {
                id: 'model2',
                name: '侨韵公园片区',
                url: './models2/tileset.json',
                visible: true,
                color: Cesium.Color.WHITE,
                alpha: 1.0,
                status: 'pending'
            },
            {
                id: 'model3',
                name: '汕大东海岸片区',
                url: './models3/tileset.json',
                visible: true,
                color: Cesium.Color.WHITE,
                alpha: 1.0,
                status: 'pending'
            },
            {
                id: 'model6',
                name: '东海岸',
                url: './models6/tileset.json',
                visible: true,
                color: Cesium.Color.WHITE,
                alpha: 1.0,
                status: 'pending'
            }
        ];

        // 拖动相关变量
        let isDragging = false;
        let dragOffset = { x: 0, y: 0 };
        let infoPanel = null;
        let footprintsVisible = true;
        let selectionEnabled = true;
        let searchResults = [];
        let isSearchActive = false;

        // 建筑底面控制变量
        let labelsVisible = false;

        // 搜索相关变量
        let schoolFootprints = [];
        let schoolFootprintDataSource = null;

        // 初始化信息面板拖动功能
        function initializeDragFunctionality() {
            infoPanel = document.getElementById('buildingInfoPanel');
            const header = document.getElementById('panelHeader');

            if (!infoPanel || !header) return;

            header.addEventListener('mousedown', startDrag, false);
            document.addEventListener('mousemove', drag, false);
            document.addEventListener('mouseup', endDrag, false);

            console.log('拖动功能已初始化');
        }

        function startDrag(e) {
            isDragging = true;
            const rect = infoPanel.getBoundingClientRect();
            dragOffset.x = e.clientX - rect.left;
            dragOffset.y = e.clientY - rect.top;

            e.preventDefault();
            e.stopPropagation();

            infoPanel.style.zIndex = '10001';
            infoPanel.style.cursor = 'grabbing';

            console.log('开始拖动面板');
        }

        function drag(e) {
            if (!isDragging || !infoPanel) return;

            e.preventDefault();
            e.stopPropagation();

            let newX = e.clientX - dragOffset.x;
            let newY = e.clientY - dragOffset.y;

            const maxX = window.innerWidth - infoPanel.offsetWidth;
            const maxY = window.innerHeight - infoPanel.offsetHeight;

            newX = Math.max(0, Math.min(newX, maxX));
            newY = Math.max(0, Math.min(newY, maxY));

            infoPanel.style.left = newX + 'px';
            infoPanel.style.top = newY + 'px';
        }

        function endDrag(e) {
            if (isDragging) {
                isDragging = false;
                if (infoPanel) {
                    infoPanel.style.zIndex = '10000';
                    infoPanel.style.cursor = 'default';
                }
                console.log('结束拖动面板');
            }
        }

        // 加载多个3D模型
        async function loadAllModels() {
            console.log('开始加载多个3D模型');

            // 清理现有模型
            tilesets.forEach(tileset => {
                if (tileset && viewer.scene.primitives.contains(tileset)) {
                    viewer.scene.primitives.remove(tileset);
                }
            });
            tilesets = [];

            let allBoundingSpheres = [];
            let loadedCount = 0;

            for (const config of modelConfigs) {
                try {
                    console.log(`开始加载模型: ${config.name} (${config.url})`);
                    config.status = 'loading';
                    updateModelManagerUI();

                    // 改进的模型文件检查逻辑
                    try {
                        const response = await fetch(config.url);
                        if (!response.ok) {
                            throw new Error(`HTTP ${response.status}: ${response.statusText}`);
                        }

                        // 检查响应的Content-Type，确保是JSON
                        const contentType = response.headers.get('content-type') || '';
                        if (!contentType.includes('application/json') && !contentType.includes('text/json')) {
                            throw new Error(`响应类型错误: ${contentType}，期望JSON格式`);
                        }

                        // 尝试解析JSON以验证文件格式
                        const jsonData = await response.json();
                        if (!jsonData.asset || !jsonData.root) {
                            throw new Error('不是有效的3D Tiles JSON格式');
                        }

                        console.log(`模型文件验证成功: ${config.name}`);

                    } catch (fetchError) {
                        console.warn(`模型文件验证失败，跳过: ${config.url}`);
                        console.warn('错误详情:', fetchError.message);
                        config.status = 'error';
                        updateModelManagerUI();
                        continue;
                    }

                    // 创建Cesium 3D Tileset
                    const tilesetInstance = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
                        url: config.url,
                        maximumScreenSpaceError: 1,
                        maximumMemoryUsage: 2048,
                        skipLevelOfDetail: false,
                        baseScreenSpaceError: 1024,
                        skipScreenSpaceErrorFactor: 16,
                        skipLevels: 1,
                        immediatelyLoadDesiredLevelOfDetail: false,
                        loadSiblings: false,
                        dynamicScreenSpaceError: true,
                        dynamicScreenSpaceErrorDensity: 0.00278,
                        dynamicScreenSpaceErrorFactor: 4.0,
                        dynamicScreenSpaceErrorHeightFalloff: 0.25,
                        preloadWhenHidden: false,
                        preloadFlightDestinations: false,
                        preferLeaves: true,
                        progressiveResolutionHeightFraction: 0.3,
                        cullWithChildrenBounds: true,
                        cullRequestsWhileMoving: true,
                        cullRequestsWhileMovingMultiplier: 60.0,
                        maximumCacheOverflowRatio: 0.1,
                        foveatedScreenSpaceError: true,
                        foveatedConeSize: 0.1,
                        foveatedMinimumScreenSpaceErrorRelaxation: 0.0
                    }));

                    // 存储模型信息
                    tilesetInstance.modelConfig = config;
                    tilesetInstance.show = config.visible;
                    tilesets.push(tilesetInstance);

                    // 设置为主模型（如果是第一个）
                    if (config.id === 'model_main') {
                        tileset = tilesetInstance;
                    }

                    // 添加详细的加载状态监控
                    tilesetInstance.loadProgress.addEventListener((numberOfPendingRequests, numberOfTilesProcessing) => {
                        if (numberOfPendingRequests === 0 && numberOfTilesProcessing === 0) {
                            console.log(`${config.name} 所有瓦片加载完成`);
                        }
                    });

                    tilesetInstance.readyPromise.then(() => {
                        const boundingSphere = tilesetInstance.boundingSphere;
                        if (!boundingSphere) {
                            throw new Error(`无法获取模型 ${config.name} 的包围球`);
                        }

                        allBoundingSpheres.push(boundingSphere);
                        loadedCount++;

                        tilesetInstance.shadows = Cesium.ShadowMode.DISABLED;  // 改为DISABLED
                        tilesetInstance.colorBlendMode = Cesium.ColorBlendMode.REPLACE;

                        // 应用模型样式
                        applyModelStyle(tilesetInstance, config);
                        config.status = 'loaded';

                        console.log(`模型加载完成: ${config.name} (${loadedCount}/${modelConfigs.length})`);
                        console.log(`   包围球中心: [${boundingSphere.center.x.toFixed(2)}, ${boundingSphere.center.y.toFixed(2)}, ${boundingSphere.center.z.toFixed(2)}]`);
                        console.log(`   包围球半径: ${boundingSphere.radius.toFixed(2)}`);
                        updateModelManagerUI();

                        // 如果是第一个加载完成的模型，设置全局中心和半径
                        if (loadedCount === 1 || config.id === 'model_main') {
                            modelCenter = boundingSphere.center;
                            modelRadius = boundingSphere.radius;
                            console.log(` 设置全局模型中心和半径: ${config.name}`);
                        }

                        // 如果所有能成功加载的模型都完成了，设置视角
                        const successfulConfigs = modelConfigs.filter(c => c.status === 'loaded');
                        if (loadedCount === successfulConfigs.length) {
                            console.log(`所有模型加载完成，设置视角。成功加载 ${loadedCount} 个模型`);
                            setViewForAllModels(allBoundingSpheres);
                        }
                    }).catch(error => {
                        console.error(`模型就绪失败: ${config.name}`, error);
                        console.error('错误详情:', {
                            name: error.name,
                            message: error.message,
                            stack: error.stack.split('\n').slice(0, 3).join('\n')
                        });
                        config.status = 'error';
                        updateModelManagerUI();
                    });

                } catch (error) {
                    console.error(`创建模型失败: ${config.name}`, error);
                    config.status = 'error';
                    updateModelManagerUI();
                }
            }

            // 添加超时检查，防止无限等待
            setTimeout(() => {
                const pendingConfigs = modelConfigs.filter(c => c.status === 'loading');
                if (pendingConfigs.length > 0) {
                    console.warn(`以下模型加载超时，可能存在问题:`, pendingConfigs.map(c => c.name));
                }
            }, 30000); // 30秒超时
        }

        // 应用模型样式
        function applyModelStyle(tileset, config) {
            tileset.style = new Cesium.Cesium3DTileStyle({
                color: {
                    conditions: [
                        ['true', `color('${config.color.toCssColorString()}', ${config.alpha})`]
                    ]
                }
            });
        }

        // 设置查看所有模型的视角
        function setViewForAllModels(boundingSpheres) {
            if (boundingSpheres.length === 0) return;

            // 计算所有模型的包围盒
            let combinedBoundingSphere;
            if (boundingSpheres.length === 1) {
                combinedBoundingSphere = boundingSpheres[0];
            } else {
                // 合并多个包围球
                const positions = boundingSpheres.map(bs => bs.center);
                combinedBoundingSphere = Cesium.BoundingSphere.fromPoints(positions);

                // 扩展半径以包含所有模型
                boundingSpheres.forEach(bs => {
                    const distance = Cesium.Cartesian3.distance(combinedBoundingSphere.center, bs.center);
                    combinedBoundingSphere.radius = Math.max(combinedBoundingSphere.radius, distance + bs.radius);
                });
            }

            // 设置全局模型中心和半径
            modelCenter = combinedBoundingSphere.center;
            modelRadius = combinedBoundingSphere.radius;

            // 飞行到查看所有模型
            viewer.camera.flyToBoundingSphere(combinedBoundingSphere, {
                duration: 1.5,
                offset: new Cesium.HeadingPitchRange(0, -0.5, combinedBoundingSphere.radius * 2.0)
            });
        }

        // 更新模型管理界面
        function updateModelManagerUI() {
            const modelList = document.getElementById('modelList');
            modelList.innerHTML = '';

            modelConfigs.forEach((config, index) => {
                const tilesetInstance = tilesets.find(ts => ts.modelConfig && ts.modelConfig.id === config.id);

                let statusText = '';
                let statusClass = '';
                switch (config.status) {
                    case 'pending':
                        statusText = '待加载';
                        statusClass = 'status-pending';
                        break;
                    case 'loading':
                        statusText = '加载中';
                        statusClass = 'status-loading';
                        break;
                    case 'loaded':
                        statusText = '已加载';
                        statusClass = 'status-loaded';
                        break;
                    case 'error':
                        statusText = '加载失败';
                        statusClass = 'status-error';
                        break;
                }

                const modelItem = document.createElement('div');
                modelItem.className = 'model-item';
                modelItem.innerHTML = `
                    <h4>
                        ${config.name}
                        <span class="load-status ${statusClass}">${statusText}</span>
                    </h4>
                    
                    <div class="model-controls">
                        <label>
                            <input type="checkbox" ${config.visible ? 'checked' : ''} 
                                   onchange="toggleModelVisibility('${config.id}', this.checked)"
                                   ${config.status !== 'loaded' ? 'disabled' : ''}>
                            显示
                        </label>
                    </div>

                    <div class="model-controls">
                        <label>透明度:</label>
                        <input type="range" min="0" max="1" step="0.1" value="${config.alpha}"
                               onchange="updateModelAlpha('${config.id}', this.value)"
                               ${config.status !== 'loaded' ? 'disabled' : ''}>
                        <span class="range-value">${Math.round(config.alpha * 100)}%</span>
                    </div>

                    <div class="model-controls">
                        <label>颜色:</label>
                        <input type="color" class="color-picker" value="${config.color.toCssHexString()}"
                               onchange="updateModelColor('${config.id}', this.value)"
                               ${config.status !== 'loaded' ? 'disabled' : ''}>
                        <button class="model-button locate-btn" onclick="flyToModel('${config.id}')" 
                                ${config.status !== 'loaded' ? 'disabled' : ''}>
                            定位
                        </button>
                        <button class="model-button delete-btn" onclick="toggleModelVisibility('${config.id}', false)">
                            隐藏
                        </button>
                    </div>

                    <div style="margin-top: 8px; font-size: 10px; color: #888; word-break: break-all;">
                        路径: ${config.url}
                    </div>
                `;
                modelList.appendChild(modelItem);
            });
        }

        // 模型管理功能函数
        function toggleModelManager() {
            const panel = document.getElementById('modelManagerPanel');
            panel.style.display = panel.style.display === 'none' ? 'block' : 'none';
            if (panel.style.display === 'block') {
                updateModelManagerUI();
            }
        }

        function toggleModelVisibility(modelId, visible) {
            const config = modelConfigs.find(c => c.id === modelId);
            const tilesetInstance = tilesets.find(ts => ts.modelConfig && ts.modelConfig.id === modelId);

            if (config && tilesetInstance) {
                config.visible = visible;
                tilesetInstance.show = visible;
            }
        }

        function updateModelAlpha(modelId, alpha) {
            const config = modelConfigs.find(c => c.id === modelId);
            const tilesetInstance = tilesets.find(ts => ts.modelConfig && ts.modelConfig.id === modelId);

            if (config && tilesetInstance) {
                config.alpha = parseFloat(alpha);
                applyModelStyle(tilesetInstance, config);
                updateModelManagerUI();
            }
        }

        function updateModelColor(modelId, colorHex) {
            const config = modelConfigs.find(c => c.id === modelId);
            const tilesetInstance = tilesets.find(ts => ts.modelConfig && ts.modelConfig.id === modelId);

            if (config && tilesetInstance) {
                config.color = Cesium.Color.fromCssColorString(colorHex);
                applyModelStyle(tilesetInstance, config);
            }
        }

        function flyToModel(modelId) {
            const tilesetInstance = tilesets.find(ts => ts.modelConfig && ts.modelConfig.id === modelId);
            if (tilesetInstance && tilesetInstance.boundingSphere) {
                viewer.camera.flyToBoundingSphere(tilesetInstance.boundingSphere, {
                    duration: 1.5,
                    offset: new Cesium.HeadingPitchRange(0, -0.5, tilesetInstance.boundingSphere.radius * 2.0)
                });
            }
        }

        function resetAllModelsView() {
            const loadedTilesets = tilesets.filter(ts => ts.boundingSphere);
            if (loadedTilesets.length > 0) {
                const boundingSpheres = loadedTilesets.map(ts => ts.boundingSphere);
                setViewForAllModels(boundingSpheres);
            }
        }

        // 加载建筑底面数据
        async function loadBuildingFootprints() {
            try {
                console.log('开始加载建筑底面数据...');

                // 创建数据源
                buildingFootprintDataSource = new Cesium.GeoJsonDataSource();
                await viewer.dataSources.add(buildingFootprintDataSource);

                // 加载GeoJSON数据
                const response = await fetch('./dc/buildings.geojson');
                if (!response.ok) {
                    throw new Error(`HTTP error! status: ${response.status}`);
                }

                const geojsonData = await response.json();
                console.log('GeoJSON数据加载成功，建筑数量:', geojsonData.features.length);

                // 使用Cesium的GeoJsonDataSource加载数据
                await buildingFootprintDataSource.load(geojsonData, {
                    clampToGround: true
                });

                // 为每个建筑设置样式和属性
                const entities = buildingFootprintDataSource.entities.values;
                for (let i = 0; i < entities.length; i++) {
                    const entity = entities[i];
                    const feature = geojsonData.features[i];

                    // 设置建筑底面样式
                    if (entity.polygon) {
                        entity.polygon.material = Cesium.Color.CYAN.withAlpha(0.01);
                        entity.polygon.outline = true;
                        entity.polygon.outlineColor = Cesium.Color.CYAN.withAlpha(0.01);  // 边框
                        entity.polygon.outlineWidth = 2;
                        entity.polygon.height = 0;
                        entity.polygon.extrudedHeight = feature.properties.height + 13; // 默认高度20米
                    }

                    // 设置建筑属性
                    entity.name = feature.properties.name || `建筑 ${feature.properties.id}`;
                    entity.description = `
                        <table>
                            <tr><td>建筑名称:</td><td>${feature.properties.name || '未命名'}</td></tr>
                            <tr><td>建筑ID:</td><td>${feature.properties.id}</td></tr>
                            <tr><td>建筑面积:</td><td>${feature.properties.area ? feature.properties.area.toFixed(2) : '未知'} 平方米</td></tr>
                            <tr><td>土地面积:</td><td>${feature.properties.tdArea ? feature.properties.tdArea.toFixed(2) : '未知'} 平方米</td></tr>
                            <tr><td>高度:</td><td>${feature.properties.height || '未设置'} 米</td></tr>
                            <tr><td>开发商:</td><td>${feature.properties.developer || '未知'}</td></tr>
                            <tr><td>预售许可:</td><td>${feature.properties.PresalePer || '未设置'}</td></tr>
                            <tr><td>竣工验收:</td><td>${feature.properties.Completion || '未设置'}</td></tr>
                            <tr><td>备注:</td><td>${feature.properties.note || '无'}</td></tr>
                        </table>
                    `;

                    // 存储GeoJSON属性到entity（修复字段映射）
                    entity.buildingData = {
                        id: feature.properties.id,
                        area: feature.properties.area,
                        height: feature.properties.height,
                        name: feature.properties.name,
                        PresalePer: feature.properties.PresalePer,
                        Completion: feature.properties.Completion,
                        developer: feature.properties.developer,
                        note: feature.properties.note,
                        tdArea: feature.properties.tdArea,
                        contractor: feature.properties.contractor,
                        landProper: feature.properties.landProper,
                        coordinates: feature.geometry.coordinates
                    };

                    buildingFootprints.push(entity);
                }

                console.log('建筑底面数据加载完成，共', entities.length, '个建筑');

            } catch (error) {
                console.error('加载建筑底面数据失败:', error);
            }
        }

        // 加载学校底面数据
        async function loadSchoolFootprints() {
            try {
                // 创建学校数据源
                schoolFootprintDataSource = new Cesium.GeoJsonDataSource();
                await viewer.dataSources.add(schoolFootprintDataSource);

                // 加载学校GeoJSON数据
                const response = await fetch('./schools/schools.geojson');
                if (!response.ok) {
                    throw new Error(`HTTP error! status: ${response.status}`);
                }

                const geojsonData = await response.json();
                console.log('学校数据加载成功，学校数量:', geojsonData.features.length);

                // 使用Cesium的GeoJsonDataSource加载数据
                await schoolFootprintDataSource.load(geojsonData, {
                    clampToGround: true
                });

                // 为每个学校设置样式和属性
                const entities = schoolFootprintDataSource.entities.values;
                console.log('学校实体数量:', entities.length);

                for (let i = 0; i < entities.length; i++) {
                    const entity = entities[i];
                    const feature = geojsonData.features[i];

                    console.log(`处理学校 ${i + 1}:`, feature.properties.schoolName);

                    // 设置学校底面样式  透明橙色
                    if (entity.polygon) {
                        entity.polygon.material = Cesium.Color.ORANGE.withAlpha(0.3);
                        entity.polygon.outline = true;
                        entity.polygon.outlineColor = Cesium.Color.ORANGE;
                        entity.polygon.outlineWidth = 2;
                        entity.polygon.height = 0;
                        entity.polygon.extrudedHeight = feature.properties.height || 30;
                    }

                    // 计算学校区域中心点
                    const coordinates = feature.geometry.coordinates[0][0];
                    let centerLon = 0, centerLat = 0;
                    coordinates.forEach(coord => {
                        centerLon += coord[0];
                        centerLat += coord[1];
                    });
                    centerLon /= coordinates.length;
                    centerLat /= coordinates.length;

                    console.log(`学校 ${feature.properties.schoolName} 中心点:`, centerLon, centerLat);

                    // 创建独立的标签实体
                    const labelEntity = viewer.entities.add({
                        position: Cesium.Cartesian3.fromDegrees(centerLon, centerLat, (feature.properties.height || 30) + 50),
                        label: {
                            text: feature.properties.schoolName || `学校${feature.properties.id}`,
                            font: 'bold 20pt sans-serif',
                            fillColor: Cesium.Color.WHITE,
                            outlineColor: Cesium.Color.BLACK,
                            outlineWidth: 2,
                            style: Cesium.LabelStyle.FILL_AND_OUTLINE,
                            pixelOffset: new Cesium.Cartesian2(0, 0),
                            showBackground: false,  // 改为false，不显示背景
                            scale: 1.2,
                            distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0.0, 8000.0),
                            heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND,
                            disableDepthTestDistance: Number.POSITIVE_INFINITY
                        }
                    });

                    // 存储学校数据
                    entity.schoolData = {
                        id: feature.properties.id,
                        schoolName: feature.properties.schoolName,
                        note: feature.properties.note,
                        height: feature.properties.height,
                        coordinates: feature.geometry.coordinates,
                        labelEntity: labelEntity  // 保存标签实体的引用
                    };

                    // 标记为学校类型
                    entity.entityType = 'school';

                    schoolFootprints.push(entity);
                }

                console.log('学校底面数据加载完成，共', entities.length, '个学校');

            } catch (error) {
                console.error('加载学校底面数据失败:', error);
            }
        }

        // 根据屏幕坐标查找对应的建筑底面
        function findBuildingByScreenPosition(position) {
            const pickedObjects = viewer.scene.drillPick(position);

            for (let i = 0; i < pickedObjects.length; i++) {
                const picked = pickedObjects[i];
                if (picked.id && picked.id.buildingData) {
                    return picked.id;
                }
            }
            return null;
        }

        // 根据世界坐标查找最近的建筑
        function findNearestBuilding(worldPosition) {
            const cartographic = Cesium.Cartographic.fromCartesian(worldPosition);
            const longitude = Cesium.Math.toDegrees(cartographic.longitude);
            const latitude = Cesium.Math.toDegrees(cartographic.latitude);

            let nearestBuilding = null;
            let minDistance = Infinity;

            buildingFootprints.forEach(building => {
                if (building.polygon && building.polygon.hierarchy) {
                    // 获取建筑多边形的中心点
                    const positions = building.polygon.hierarchy.getValue();
                    if (positions && positions.length > 0) {
                        // 计算多边形中心
                        let centerLon = 0, centerLat = 0;
                        positions.forEach(pos => {
                            const cart = Cesium.Cartographic.fromCartesian(pos);
                            centerLon += Cesium.Math.toDegrees(cart.longitude);
                            centerLat += Cesium.Math.toDegrees(cart.latitude);
                        });
                        centerLon /= positions.length;
                        centerLat /= positions.length;

                        // 计算距离
                        const distance = Math.sqrt(
                            Math.pow(longitude - centerLon, 2) +
                            Math.pow(latitude - centerLat, 2)
                        );

                        if (distance < minDistance) {
                            minDistance = distance;
                            nearestBuilding = building;
                        }
                    }
                }
            });

            // 如果最近距离小于阈值，返回建筑
            return minDistance < 0.001 ? nearestBuilding : null; // 约100米的阈值
        }

        // 高亮选中的建筑
        function highlightBuilding(building) {
            // 移除之前的高亮
            clearBuildingHighlight();

            if (building && building.polygon) {
                // 保存原始材质
                building.originalMaterial = building.polygon.material;
                building.originalOutlineColor = building.polygon.outlineColor;
                building.originalOutlineWidth = building.polygon.outlineWidth;

                // 设置高亮样式
                building.polygon.material = Cesium.Color.YELLOW.withAlpha(0.15);
                // building.polygon.outlineColor = Cesium.Color.RED;
                building.polygon.outlineColor = Cesium.Color.YELLOW.withAlpha(0.2);

                building.polygon.outlineWidth = 4;

                console.log('已高亮建筑:', building.name);
            }
        }

        // 清除建筑高亮
        function clearBuildingHighlight() {
            if (selectedBuilding && selectedBuilding.polygon) {
                // 恢复原始样式
                selectedBuilding.polygon.material = selectedBuilding.originalMaterial || Cesium.Color.CYAN.withAlpha(0.01); // 保持几乎透明
                selectedBuilding.polygon.outlineColor = selectedBuilding.originalOutlineColor || Cesium.Color.CYAN.withAlpha(0.01); // 边框也保持几乎透明
                selectedBuilding.polygon.outlineWidth = selectedBuilding.originalOutlineWidth || 2;
            }
        }

        // 显示建筑信息面板
        function showBuildingInfo(building, screenPosition) {
            if (!infoPanel || !building) return;

            const buildingData = building.buildingData || {};

            // 计算建筑中心坐标
            let centerLon = '未知', centerLat = '未知';
            if (building.polygon && building.polygon.hierarchy) {
                const positions = building.polygon.hierarchy.getValue();
                if (positions && positions.length > 0) {
                    let totalLon = 0, totalLat = 0;
                    positions.forEach(pos => {
                        const cart = Cesium.Cartographic.fromCartesian(pos);
                        totalLon += Cesium.Math.toDegrees(cart.longitude);
                        totalLat += Cesium.Math.toDegrees(cart.latitude);
                    });
                    centerLon = (totalLon / positions.length).toFixed(6);
                    centerLat = (totalLat / positions.length).toFixed(6);
                }
            }

            // 统一的空值处理函数
            function formatValue(value, defaultText = '暂无数据') {
                if (value === null || value === undefined || value === '' || value === 'null') {
                    return defaultText;
                }
                return value;
            }

            // 格式化日期函数
            function formatDate(dateString) {
                if (!dateString || dateString === 'null' || dateString === null) {
                    return '暂无数据';
                }
                try {
                    const date = new Date(dateString);
                    return date.toLocaleDateString('zh-CN');
                } catch (e) {
                    return '暂无数据';
                }
            }

            // 格式化面积函数
            function formatArea(area) {
                if (!area || area === 'null' || area === null) {
                    return '暂无数据';
                }
                try {
                    return parseFloat(area).toLocaleString() + ' m²';
                } catch (e) {
                    return '暂无数据';
                }
            }

            // 格式化高度函数
            function formatHeight(height) {
                if (!height || height === 'null' || height === null) {
                    return '暂无数据';
                }
                try {
                    return parseFloat(height).toFixed(2) + ' 米';
                } catch (e) {
                    return '暂无数据';
                }
            }

            // 更新面板标题为建筑名称
            const panelHeader = document.querySelector('.panel-header h3');
            if (panelHeader) {
                panelHeader.innerHTML = `${formatValue(buildingData.name, '未命名建筑')}`;
            }

            // 填充面板内容
            const panelContent = document.getElementById('panelContent');
            panelContent.innerHTML = `
                <div class="info-section status-section">
                    <strong style="color: #00ff00;">项目时间节点</strong><br>
                    <span style="color: #90ee90;">竣工时间: ${formatDate(buildingData.Completion)}</span><br>
                </div>

                <div class="info-grid">
                    <div class="info-box" style="grid-column: 1 / -1;">
                        <strong style="color: #ffff00;">开发商:</strong><br>
                        <span style="color: #90ee90; font-size: 12px;">${formatValue(buildingData.developer)}</span>
                    </div>
                </div>

                <div class="info-grid">
                    <div class="info-box" style="grid-column: 1 / -1;">
                        <strong style="color: #ffff00;">承建商:</strong><br>
                        <span style="color: #90ee90; font-size: 12px;">${formatValue(buildingData.contractor)}</span>
                    </div>
                </div>  

                <div class="info-grid">
                    <div class="info-box">
                        <strong style="color: #ffff00;">建筑面积:</strong><br>
                        <span style="color: #87ceeb; font-family: monospace;">${formatArea(buildingData.area)}</span>
                    </div>
                    <div class="info-box">
                        <strong style="color: #ffff00;">土地面积:</strong><br>
                        <span style="color: #87ceeb; font-family: monospace;">${formatArea(buildingData.tdArea)}</span>
                    </div>
                </div>

                <div class="info-grid">
                    <div class="info-box" style="grid-column: 1 / -1;">
                        <strong style="color: #ffff00;">土地性质:</strong><br>
                        <span style="color: #90ee90; font-size: 12px;">${formatValue(buildingData.landProper)}</span>
                    </div>
                </div>
                                
                ${buildingData.note && buildingData.note !== 'null' && buildingData.note !== null ? `
                <div class="info-section" style="background: rgba(255, 165, 0, 0.1); border-left: 3px solid #ffa500;">
                    <strong style="color: #ffa500;">备注信息:</strong><br>
                    <span style="color: #ffd700;">${formatValue(buildingData.note)}</span>
                </div>
                ` : ''}
                
                <div class="button-group">
                    <button class="panel-button close-button" onclick="deselectBuilding()">
                        取消选中
                    </button>
                </div>
            `;

            // 设置面板位置
            const maxLeft = window.innerWidth - 450;
            const maxTop = window.innerHeight - 500;

            infoPanel.style.left = Math.min(screenPosition.x + 20, maxLeft) + 'px';
            infoPanel.style.top = Math.min(screenPosition.y - 20, maxTop) + 'px';

            // 显示面板
            infoPanel.style.display = 'block';
            infoPanel.style.opacity = '1';
            infoPanel.style.transform = 'scale(1)';

            console.log('已显示建筑信息面板');
        }

        // 隐藏建筑信息面板
        function hideBuildingInfo() {
            if (infoPanel) {
                infoPanel.style.display = 'none';
                console.log('已隐藏信息面板');
            }
        }

        // 选择建筑（整合3D模型和建筑底面）
        function selectBuilding(pickedFeature, screenPosition) {
            if (!selectionEnabled) return;

            console.log('选择建筑功能被调用');

            // 取消之前的选中
            deselectBuilding();

            let buildingToSelect = null;

            // 首先尝试从建筑底面数据中查找
            buildingToSelect = findBuildingByScreenPosition(screenPosition);

            // 如果没找到，尝试根据3D模型位置查找最近的建筑
            if (!buildingToSelect && pickedFeature) {
                const worldPosition = viewer.scene.pickPosition(screenPosition);
                if (worldPosition) {
                    buildingToSelect = findNearestBuilding(worldPosition);
                }
            }

            if (buildingToSelect) {
                selectedBuilding = buildingToSelect;

                // 高亮建筑底面
                highlightBuilding(buildingToSelect);

                // 显示建筑信息
                showBuildingInfo(buildingToSelect, screenPosition);

                console.log('已选中建筑:', buildingToSelect.name);
            } else {
                console.log('未找到对应的建筑数据');
            }
        }

        // 取消选中建筑
        function deselectBuilding() {
            console.log('取消选中建筑');

            if (selectedBuilding) {
                clearBuildingHighlight();
                selectedBuilding = null;
            }

            hideBuildingInfo();
            console.log('已取消选中');
        }


        // 切换建筑底面显示
        function toggleBuildingFootprints() {
            const checkbox = document.getElementById('showFootprints');
            footprintsVisible = checkbox.checked;

            if (buildingFootprintDataSource) {
                buildingFootprintDataSource.show = footprintsVisible;
                console.log('建筑底面显示:', footprintsVisible ? '开启' : '关闭');
            }
        }

        // 切换建筑选择功能
        function toggleBuildingSelection() {
            const checkbox = document.getElementById('enableSelection');
            selectionEnabled = checkbox.checked;

            if (!selectionEnabled) {
                deselectBuilding();
            }

            console.log('建筑选择功能:', selectionEnabled ? '启用' : '禁用');
        }

        // 视角控制函数
        function setView(heading, pitch, range) {
            if (viewer && modelCenter && modelRadius) {
                const cartographic = Cesium.Cartographic.fromCartesian(modelCenter);
                viewer.camera.flyTo({
                    destination: Cesium.Cartesian3.fromRadians(
                        cartographic.longitude,
                        cartographic.latitude,
                        cartographic.height + range
                    ),
                    orientation: {
                        heading: heading,
                        pitch: pitch,
                        roll: 0.0
                    },
                    duration: 1.5
                });
            }
        }

        // 各种视角函数
        function topView() {
            setView(0, -Cesium.Math.PI_OVER_TWO, modelRadius * 3);
        }

        function frontView() {
            setView(0, -0.3, modelRadius * 2);
        }

        function leftView() {
            setView(-Cesium.Math.PI_OVER_TWO, -0.3, modelRadius * 2);
        }

        function rightView() {
            setView(Cesium.Math.PI_OVER_TWO, -0.3, modelRadius * 2);
        }

        function resetView() {
            if (viewer && modelCenter && modelRadius) {
                viewer.camera.flyTo({
                    destination: Cesium.Cartesian3.fromRadians(
                        Cesium.Cartographic.fromCartesian(modelCenter).longitude,
                        Cesium.Cartographic.fromCartesian(modelCenter).latitude,
                        modelRadius * 2.5
                    ),
                    orientation: {
                        heading: 0.0,
                        pitch: -0.5,
                        roll: 0.0
                    },
                    duration: 2.0
                });
            }
        }

        // 性能监控
        function togglePerformance() {
            const panel = document.getElementById('performancePanel');
            panel.style.display = panel.style.display === 'none' ? 'block' : 'none';
        }

        // 初始化搜索功能
        function initializeSearch() {
            const searchInput = document.getElementById('buildingSearchInput');
            const searchButton = document.getElementById('searchButton');
            const clearButton = document.getElementById('clearSearchButton');
            const resultsContainer = document.getElementById('searchResults');

            if (!searchInput || !searchButton || !clearButton) return;

            // 搜索输入事件
            searchInput.addEventListener('input', function (e) {
                const query = e.target.value.trim();
                if (query.length >= 1) {
                    performSearch(query);
                } else {
                    hideSearchResults();
                }
            });

            // 回车搜索
            searchInput.addEventListener('keypress', function (e) {
                if (e.key === 'Enter') {
                    const query = e.target.value.trim();
                    if (query) {
                        performSearch(query);
                    }
                }
            });

            // 搜索按钮点击
            searchButton.addEventListener('click', function () {
                const query = searchInput.value.trim();
                if (query) {
                    performSearch(query);
                }
            });

            // 清除搜索
            clearButton.addEventListener('click', function () {
                clearSearch();
            });

            console.log('搜索功能初始化完成');
        }

        // 执行搜索
        function performSearch(query) {
            if (!buildingFootprints || buildingFootprints.length === 0) {
                console.warn('建筑数据未加载完成');
                return;
            }

            const results = [];
            const queryLower = query.toLowerCase();

            // 模糊搜索建筑名称
            buildingFootprints.forEach(building => {
                const buildingData = building.buildingData || {};
                const name = buildingData.name || '';

                if (name.toLowerCase().includes(queryLower)) {
                    results.push({
                        building: building,
                        name: name,
                        id: buildingData.id,
                        developer: buildingData.developer || '未知',
                        area: buildingData.area || 0
                    });
                }
            });

            searchResults = results;
            displaySearchResults(results, query);

            // 显示清除按钮
            document.getElementById('clearSearchButton').style.display = 'block';
            isSearchActive = true;

            console.log(`搜索 "${query}" 找到 ${results.length} 个结果`);
        }

        // 显示搜索结果
        function displaySearchResults(results, query) {
            const resultsContainer = document.getElementById('searchResults');

            if (results.length === 0) {
                resultsContainer.innerHTML = `
                    <div class="no-results">
                        未找到包含 "${query}" 的建筑
                    </div>
                `;
                resultsContainer.style.display = 'block';
                return;
            }

            let html = '';
            results.forEach((result, index) => {
                const area = result.area ? `${parseFloat(result.area).toLocaleString()} m²` : '未知';
                html += `
                    <div class="search-result-item" onclick="selectSearchResult(${index})">
                        <div class="search-result-name">${highlightQuery(result.name, query)}</div>
                        <div class="search-result-info">
                            ID: ${result.id} | 面积: ${area} | 开发商: ${result.developer}
                        </div>
                    </div>
                `;
            });

            resultsContainer.innerHTML = html;
            resultsContainer.style.display = 'block';
        }

        // 高亮搜索关键词
        function highlightQuery(text, query) {
            if (!query) return text;
            const regex = new RegExp(`(${query})`, 'gi');
            return text.replace(regex, '<span style="background: yellow; color: black;">$1</span>');
        }

        // 选择搜索结果
        function selectSearchResult(index) {
            if (index >= 0 && index < searchResults.length) {
                const result = searchResults[index];
                const building = result.building;

                // 取消之前的选中
                deselectBuilding();

                // 直接选中搜索到的建筑
                selectedBuilding = building;

                // 高亮建筑底面
                highlightBuilding(building);

                // 显示建筑信息面板（使用屏幕中心位置）
                const screenPosition = {
                    x: window.innerWidth / 2,
                    y: window.innerHeight / 2
                };
                showBuildingInfo(building, screenPosition);

                // 隐藏搜索结果
                hideSearchResults();

                // 飞行到建筑位置
                flyToBuildingFromSearch(building);

                console.log('已选中搜索结果:', result.name);
            }
        }

        // 从搜索结果飞行到建筑 - 鲁棒版
        function flyToBuildingFromSearch(building) {
            console.log('开始飞行到建筑:', building.buildingData?.name);

            if (!building || !viewer) {
                console.error('建筑对象或viewer未初始化');
                return;
            }

            try {
                let centerLon, centerLat, buildingHeight;

                // 方法1：尝试使用polygon hierarchy
                if (building.polygon && building.polygon.hierarchy) {
                    try {
                        const positions = building.polygon.hierarchy.getValue(viewer.clock.currentTime);
                        if (positions && positions.length > 0) {
                            let totalLon = 0, totalLat = 0;
                            positions.forEach(pos => {
                                const cart = Cesium.Cartographic.fromCartesian(pos);
                                totalLon += Cesium.Math.toDegrees(cart.longitude);
                                totalLat += Cesium.Math.toDegrees(cart.latitude);
                            });
                            centerLon = totalLon / positions.length;
                            centerLat = totalLat / positions.length;
                            console.log('成功获取坐标');
                        }
                    } catch (e) {
                        console.warn('失败:', e.message);
                    }
                }

                // 方法2：使用存储的坐标数据
                if (!centerLon && building.buildingData && building.buildingData.coordinates) {
                    try {
                        const coords = building.buildingData.coordinates;
                        console.log('尝试使用坐标数据:', coords);

                        // 处理GeoJSON的多层数组结构
                        let flatCoords = coords;
                        while (Array.isArray(flatCoords[0]) && Array.isArray(flatCoords[0][0])) {
                            flatCoords = flatCoords[0];
                        }

                        if (flatCoords && flatCoords.length > 0) {
                            let totalLon = 0, totalLat = 0;
                            flatCoords.forEach(coord => {
                                totalLon += coord[0];
                                totalLat += coord[1];
                            });
                            centerLon = totalLon / flatCoords.length;
                            centerLat = totalLat / flatCoords.length;
                            console.log('成功获取坐标');
                        }
                    } catch (e) {
                        console.warn('失败:', e.message);
                    }

                }

                if (!centerLon || !centerLat) {
                    console.error('无法获取建筑坐标');
                    return;
                }

                buildingHeight = building.buildingData?.height || 50;
                const viewHeight = Math.max(buildingHeight * 2, 200);

                console.log(`飞行参数:`);
                console.log(`  坐标: [${centerLon.toFixed(6)}, ${centerLat.toFixed(6)}]`);
                console.log(`  观看高度: ${viewHeight}m`);

                // 执行飞行
                viewer.camera.flyTo({
                    destination: Cesium.Cartesian3.fromDegrees(centerLon, centerLat, viewHeight),
                    orientation: {
                        heading: 0.0,
                        pitch: Cesium.Math.toRadians(-60),
                        roll: 0.0
                    },
                    duration: 3.0,
                    complete: () => {
                        console.log(`飞行完成: ${building.buildingData?.name}`);
                    }
                });

            } catch (error) {
                console.error('飞行失败:', error);
            }
        }

        // 隐藏搜索结果
        function hideSearchResults() {
            const resultsContainer = document.getElementById('searchResults');
            resultsContainer.style.display = 'none';
        }

        // 清除搜索
        function clearSearch() {
            // 清空搜索框
            document.getElementById('buildingSearchInput').value = '';

            // 隐藏搜索结果和清除按钮
            hideSearchResults();
            document.getElementById('clearSearchButton').style.display = 'none';

            // 取消选中状态
            if (isSearchActive) {
                deselectBuilding();
            }

            searchResults = [];
            isSearchActive = false;

            console.log('已清除搜索');
        }

        // 初始化函数
        async function init() {
            console.log('开始初始化Cesium应用...');

            // 初始化拖动功能
            initializeDragFunctionality();

            // 使用缓存的天地图影像服务
            const tiandituImageryProvider = createCachedTiandituProvider('img', 'img');

            viewer = new Cesium.Viewer('cesiumContainer', {
                imageryProvider: tiandituImageryProvider,
                baseLayerPicker: false,
                geocoder: false,
                sceneModePicker: false,
                navigationHelpButton: false,
                animation: false,
                timeline: false,
                infoBox: false,
                fullscreenButton: true,
                homeButton: false,
                selectionIndicator: false,
                requestRenderMode: true, // 启用按需渲染
                maximumRenderTimeChange: Infinity
            });

            // 禁用不必要的效果以提高性能
            viewer.scene.fog.enabled = false;
            viewer.scene.skyAtmosphere.show = false;
            viewer.scene.sun.show = false;
            viewer.scene.moon.show = false;
            viewer.scene.skyBox = undefined;

            // 确保地球是可见的
            viewer.scene.globe.show = true;
            viewer.scene.globe.depthTestAgainstTerrain = true;

            // 使用缓存的天地图中文注记
            const tiandituLabelProvider = createCachedTiandituProvider('cia', 'cia');
            viewer.imageryLayers.addImageryProvider(tiandituLabelProvider);

            // 高质量渲染设置
            viewer.scene.highDynamicRange = true;
            viewer.scene.globe.enableLighting = false;
            viewer.scene.globe.dynamicAtmosphereLighting = false;
            viewer.scene.globe.dynamicAtmosphereLightingFromSun = false;
            viewer.scene.backgroundColor = new Cesium.Color(0.0, 0.0, 0.0, 0.0);

            // 启用抗锯齿和优化后处理
            viewer.scene.postProcessStages.fxaa.enabled = true;
            viewer.scene.msaaSamples = 4;

            // 阴影设置 - 全部禁用
            viewer.shadows = false;                    // 改为false
            viewer.shadowMap.enabled = false;         // 改为false
            viewer.shadowMap.softShadows = false;     // 改为false
            viewer.shadowMap.size = 2048;             // 保持不变
            viewer.shadowMap.maximumDistance = 5000.0; // 保持不变

            // 优化相机控制
            viewer.scene.screenSpaceCameraController.minimumZoomDistance = 1.0;
            viewer.scene.screenSpaceCameraController.maximumZoomDistance = 100000.0;
            viewer.scene.screenSpaceCameraController.enableCollisionDetection = false;

            // 加载多个3D模型
            loadAllModels().then(() => {
                // 加载建筑底面数据
                loadBuildingFootprints().then(() => {
                    // 加载学校底面数据
                    loadSchoolFootprints().then(() => {
                        // 启用建筑物点击选中功能
                        setupBuildingSelection();

                        // 初始化搜索功能
                        initializeSearch();
                    });
                });
            });

            // 建筑物选中功能设置
            function setupBuildingSelection() {
                console.log('设置建筑物选中功能...');

                // 添加点击事件处理
                viewer.cesiumWidget.screenSpaceEventHandler.setInputAction(function onLeftClick(event) {
                    // 如果正在拖动，不处理点击
                    if (isDragging) {
                        console.log('正在拖动，忽略点击');
                        return;
                    }

                    console.log('检测到点击事件:', event.position);

                    const picked = viewer.scene.pick(event.position);
                    console.log('点击检测结果:', picked);

                    if (Cesium.defined(picked)) {
                        console.log('检测到对象:', picked);

                        // 调用统一的建筑选择函数
                        selectBuilding(picked, event.position);
                    } else {
                        console.log('点击了空白处');
                        deselectBuilding();
                    }
                }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

                console.log('建筑物选中功能设置完成');
            }

            // 绑定视角控制按钮事件
            document.getElementById('topView').addEventListener('click', topView);
            document.getElementById('frontView').addEventListener('click', frontView);
            document.getElementById('leftView').addEventListener('click', leftView);
            document.getElementById('rightView').addEventListener('click', rightView);
            document.getElementById('resetView').addEventListener('click', resetView);

            console.log('Cesium应用初始化完成');
        }

        // 性能监控
        function updatePerformanceStats() {
            if (viewer && document.getElementById('performancePanel').style.display !== 'none') {
                const content = document.getElementById('performanceContent');

                const loadedModels = tilesets.filter(ts => ts.readyPromise).length;
                const totalTiles = tilesets.reduce((sum, ts) => sum + (ts.statistics ? ts.statistics.numberOfTilesTotal : 0), 0);
                const renderedTiles = tilesets.reduce((sum, ts) => sum + (ts.statistics ? ts.statistics.numberOfTilesWithContentReady : 0), 0);
                const memoryUsage = tilesets.reduce((sum, ts) => sum + (ts.statistics ? ts.statistics.geometryByteLength : 0), 0);

                content.innerHTML = `
                    <div>相机高度: <span style="color: #00ff00;">${Math.round(viewer.camera.positionCartographic.height).toLocaleString()}</span> 米</div>
                    <div>已加载模型: <span style="color: #00ff00;">${loadedModels}</span> / ${modelConfigs.length}</div>
                    <div>加载的瓦片: <span style="color: #00ff00;">${totalTiles}</span></div>
                    <div>渲染的瓦片: <span style="color: #00ff00;">${renderedTiles}</span></div>
                    <div>内存使用: <span style="color: #00ff00;">${Math.round(memoryUsage / 1024 / 1024)}</span> MB</div>
                    <div>建筑数量: <span style="color: #00ff00;">${buildingFootprints.length}</span></div>
                `;
            }
        }

        // 启动应用
        window.onload = function () {
            init();
            setInterval(updatePerformanceStats, 1000);
        };

        // 切换学校显示状态
        function toggleSchoolsVisibility() {
            const showSchoolsCheckbox = document.getElementById('showSchools');
            const isVisible = showSchoolsCheckbox.checked;

            if (schoolFootprintDataSource) {
                schoolFootprintDataSource.show = isVisible;
            }

            // 控制学校标签的显示
            schoolFootprints.forEach(school => {
                if (school.schoolData && school.schoolData.labelEntity) {
                    school.schoolData.labelEntity.show = isVisible;
                }
            });

            console.log('学校显示状态:', isVisible ? '开启' : '关闭');
        }
    </script>
</body>

</html>